home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C25 / BeeAndFlowers.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  2.4 KB  |  114 lines

  1. //: C25:BeeAndFlowers.cpp
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // Demonstration of "visitor" pattern
  7. #include "../purge.h"
  8. #include <iostream>
  9. #include <string>
  10. #include <vector>
  11. #include <algorithm>
  12. #include <cstdlib>
  13. #include <ctime>
  14. using namespace std;
  15.  
  16. class Gladiolus;
  17. class Renuculus;
  18. class Chrysanthemum;
  19.  
  20. class Visitor {
  21. public:
  22.   virtual void visit(Gladiolus* f) = 0;
  23.   virtual void visit(Renuculus* f) = 0;
  24.   virtual void visit(Chrysanthemum* f) = 0;
  25.   virtual ~Visitor() {}
  26. };
  27.  
  28. class Flower {
  29. public:
  30.   virtual void accept(Visitor&) = 0;
  31.   virtual ~Flower() {}
  32. };
  33.  
  34. class Gladiolus : public Flower {
  35. public:
  36.   virtual void accept(Visitor& v) {
  37.     v.visit(this);
  38.   }
  39. };
  40.  
  41. class Renuculus : public Flower {
  42. public:
  43.   virtual void accept(Visitor& v) {
  44.     v.visit(this);
  45.   }
  46. };
  47.  
  48. class Chrysanthemum : public Flower {
  49. public:
  50.   virtual void accept(Visitor& v) {
  51.     v.visit(this);
  52.   }
  53. };
  54.  
  55. // Add the ability to produce a string:
  56. class StringVal : public Visitor {
  57.   string s;
  58. public:
  59.   operator const string&() { return s; }
  60.   virtual void visit(Gladiolus*) {
  61.     s = "Gladiolus";
  62.   }
  63.   virtual void visit(Renuculus*) {
  64.     s = "Renuculus";
  65.   }
  66.   virtual void visit(Chrysanthemum*) {
  67.     s = "Chrysanthemum";
  68.   }
  69. };
  70.  
  71. // Add the ability to do "Bee" activities:
  72. class Bee : public Visitor {
  73. public:
  74.   virtual void visit(Gladiolus*) {
  75.     cout << "Bee and Gladiolus\n";
  76.   }
  77.   virtual void visit(Renuculus*) {
  78.     cout << "Bee and Renuculus\n";
  79.   }
  80.   virtual void visit(Chrysanthemum*) {
  81.     cout << "Bee and Chrysanthemum\n";
  82.   }
  83. };
  84.  
  85. struct FlowerGen {
  86.   FlowerGen() { srand(time(0)); }
  87.   Flower* operator()() {
  88.     switch(rand() % 3) {
  89.       default:
  90.       case 0: return new Gladiolus();
  91.       case 1: return new Renuculus();
  92.       case 2: return new Chrysanthemum();
  93.     }
  94.   }
  95. };
  96.  
  97. int main() {
  98.   vector<Flower*> v(10);
  99.   generate(v.begin(), v.end(), FlowerGen());
  100.   vector<Flower*>::iterator it;
  101.   // It's almost as if I added a virtual function
  102.   // to produce a Flower string representation:
  103.   StringVal sval;
  104.   for(it = v.begin(); it != v.end(); it++) {
  105.     (*it)->accept(sval);
  106.     cout << string(sval) << endl;
  107.   }
  108.   // Perform "Bee" operation on all Flowers:
  109.   Bee bee;
  110.   for(it = v.begin(); it != v.end(); it++)
  111.     (*it)->accept(bee);
  112.   purge(v);
  113. } ///:~
  114.